package org.javaforever.gatescore.vue;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.javaforever.gatescore.core.FrontDomain;
import org.javaforever.gatescore.core.FrontDropdown;
import org.javaforever.gatescore.core.Statement;
import org.javaforever.gatescore.core.StatementList;
import org.javaforever.gatescore.core.Writeable;
import org.javaforever.gatescore.core.WriteableUtil;
import org.javaforever.gatescore.exception.ValidateException;
import org.javaforever.gatescore.poi.SpreadSheetTranslater;

public class VuePageVars implements Comparable<VuePageVars>,Cloneable,Serializable{
	private static final long serialVersionUID = 395468887110002669L;
	protected String standardName = "PageVars";
	protected List<FrontDomain> domains = new ArrayList<FrontDomain>();
	protected FrontDomain userDomain;
	@Override
	public int compareTo(VuePageVars o) {
		return this.standardName.compareTo(o.getStandardName());
	}
	public String getStandardName() {
		return standardName;
	}
	public void setStandardName(String standardName) {
		this.standardName = standardName;
	}
	public String getFileName() {
		return this.standardName.toLowerCase()+".js";
	}
	
	public boolean isLoginDropdown(FrontDomain d) throws ValidateException {		
		if (this.userDomain!=null) {
			System.out.println("JerryDebug:userDomain:"+this.userDomain.getStandardName());
			this.userDomain = SpreadSheetTranslater.decorateDomainDropdowns(this.userDomain, domains);
			for (FrontDropdown dp: this.userDomain.getDropdownSet()) {
				FrontDomain targetDomain = dp.getTarget();
				System.out.println("JerryDebug:dp:target:"+targetDomain.getStandardName());
				if (targetDomain.getStandardName().equals(d.getStandardName())) return true;
			}
		}
		return false;
	}
	
	public StatementList generateStatementList() throws Exception{
		List<Writeable> sList = new ArrayList<Writeable>();
		sList.add(new Statement(1000L,0,"import Vue from 'vue'"));
		sList.add(new Statement(2000L,0,"import Vuex from 'vuex'"));
		long serial = 3000L;
		for (FrontDomain d : this.domains) {
			if (d!=null && !d.isLegacy()) {
				if (isLoginDropdown(d)) sList.add(new Statement(serial,0,"import { listActive"+d.getCapFirstPlural()+" } from '@/api/login'"));
				else sList.add(new Statement(serial,0,"import { listActive"+d.getCapFirstPlural()+" } from '@/api/"+d.getPlural().toLowerCase()+"'"));
				serial += 1000L;
			}
		}

		sList.add(new Statement(serial,0,""));
		sList.add(new Statement(serial+1000L,0,"Vue.use(Vuex)"));
		sList.add(new Statement(serial+2000L,0,""));
		serial += 3000L;
		for (FrontDomain d : this.domains) {
			if (d!=null && !d.isLegacy()) {
				sList.add(new Statement(serial,0,"const "+d.getLowerFirstDomainName()+"Store = new Vuex.Store({"));
				sList.add(new Statement(serial+1000L,1,d.getLowerFirstDomainName()+"Map: state => state."+d.getLowerFirstDomainName()+"Map"));
				sList.add(new Statement(serial+2000L,0,"})"));
				sList.add(new Statement(serial+3000L,0,""));
				serial += 4000L;
			}
		}

		for (FrontDomain d : this.domains) {
			if (d!=null && !d.isLegacy()) {
				sList.add(new Statement(serial,0,"function set"+d.getCapFirstDomainName()+"Map("+d.getLowerFirstDomainName()+"Map) {"));
				sList.add(new Statement(serial+1000L,1,"this."+d.getLowerFirstDomainName()+"Map = "+d.getLowerFirstDomainName()+"Map"));
				sList.add(new Statement(serial+2000L,0,"}"));
				sList.add(new Statement(serial+3000L,0,""));
				serial += 4000L;
			}
		}
		
		for (FrontDomain d : this.domains) {
			if (d!=null && !d.isLegacy()) {
				sList.add(new Statement(serial,0,"function init"+d.getCapFirstDomainName()+"Store() {"));
				sList.add(new Statement(serial+1000L,1,"listActive"+d.getCapFirstPlural()+"().then(state => {"));
				sList.add(new Statement(serial+2000L,2,"if (!!state.data.rows) {"));
				sList.add(new Statement(serial+3000L,3,"var "+d.getLowerFirstChar()+"Map = {}"));
				sList.add(new Statement(serial+4000L,3,"for (var i = 0; i < state.data.rows.length; i++) {"));
				sList.add(new Statement(serial+5000L,4,d.getLowerFirstChar()+"Map[state.data.rows[i]."+d.getDomainId().getFieldName()+"] = state.data.rows[i]."+d.getDomainName().getFieldName()));
				sList.add(new Statement(serial+6000L,3,"}"));
				sList.add(new Statement(serial+7000L,3,d.getLowerFirstDomainName()+"Store."+d.getLowerFirstDomainName()+"Map = "+d.getLowerFirstChar()+"Map"));
				sList.add(new Statement(serial+8000L,3,"console.log("+d.getLowerFirstChar()+"Map['1'])"));
				sList.add(new Statement(serial+9000L,2,"}"));
				sList.add(new Statement(serial+10000L,1,"})"));
				sList.add(new Statement(serial+11000L,0,"}"));
				sList.add(new Statement(serial+12000L,0,""));
				serial += 13000L;
			}
		}

		sList.add(new Statement(serial,0,"export default {"));
		serial += 1000L;
		for (FrontDomain d : this.domains) {
			if (d!=null && !d.isLegacy()) {
				sList.add(new Statement(serial,1,d.getLowerFirstDomainName()+"Store,"));
				sList.add(new Statement(serial+1000L,1,"set"+d.getCapFirstDomainName()+"Map,"));
				sList.add(new Statement(serial+2000L,1,"init"+d.getCapFirstDomainName()+"Store,"));
				serial += 3000L;
			}
		}
		sList.add(new Statement(serial,0,"}"));
		return WriteableUtil.merge(sList);
	}
	public List<FrontDomain> getDomains() {
		return domains;
	}
	public void setDomains(List<FrontDomain> domains) {
		this.domains = domains;
	}
	public FrontDomain getUserDomain() {
		return userDomain;
	}
	public void setUserDomain(FrontDomain userDomain) {
		this.userDomain = userDomain;
	}	
}
